package com.cloudfun.campusshare.controller.miniprogram;

import com.cloudfun.campusshare.common.constant.Code;
import com.cloudfun.campusshare.common.constant.miniprogram.WeChatReturnCode;
import com.cloudfun.campusshare.common.constant.miniprogram.WeChatTradeState;
import com.cloudfun.campusshare.common.model.dto.WeChatContractSignNotifyDTO;
import com.cloudfun.campusshare.common.model.dto.WeChatNotifyRespDTO;
import com.cloudfun.campusshare.common.model.dto.WeChatPaymentNotifyDTO;
import com.cloudfun.campusshare.configuration.property.WeChatProperties;
import com.cloudfun.campusshare.repo.OrderEntityRepo;
import com.cloudfun.campusshare.service.DeviceOrderService;
import com.cloudfun.campusshare.service.WeChatContractService;
import com.cloudfun.campusshare.service.WeChatNotifyService;
import com.cloudfun.campusshare.util.tencent.wechat.WeChatUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.SortedMap;

/**
 * Created by Huqin on 2020/4/20
 */
@Slf4j
@RestController
@RequestMapping("/v1/wechat/notify")
public class WeChatNotifyController {

    @Autowired
    private WeChatContractService weChatContractService;

    @Autowired
    private DeviceOrderService deviceOrderService;

    @Autowired
    private WeChatNotifyService weChatNotifyService;

    @Autowired
    private WeChatProperties weChatProperties;
    @Resource
    private OrderEntityRepo orderEntityRepo;

    @PostMapping(value = "/contract-sign", consumes = {MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE}, produces = MediaType.APPLICATION_XML_VALUE)
    public WeChatNotifyRespDTO contractSign(@RequestBody WeChatContractSignNotifyDTO signNotifyDTO) {
        log.info("收到免密支付签约通知：{}", signNotifyDTO);
        weChatNotifyService.create(signNotifyDTO.getMerchantId(), signNotifyDTO.getOpenId(), signNotifyDTO);
        if (signNotifyDTO.getReturnCode().equals(WeChatReturnCode.FAIL)) {
            log.error("免密支付签约失败：{}", signNotifyDTO.getReturnMsg());
            return WeChatNotifyRespDTO.success();
        }
        if (signNotifyDTO.getResultCode().equals(WeChatReturnCode.FAIL)) {
            log.error("免密支付签约失败：{}", signNotifyDTO.getResultCode());
            return WeChatNotifyRespDTO.success();
        }
        try {
            SortedMap<String, Object> params = WeChatUtil.req2Map(signNotifyDTO, true);
            boolean weChatSign = WeChatUtil.verifySign(params, weChatProperties.getApiKey());
            if (!weChatSign) {
                log.error("微信免密支付签约通知验签失败：{}", signNotifyDTO);
                return WeChatNotifyRespDTO.fail("签名失败");
            } else {
                return weChatContractService.notify(signNotifyDTO);
            }
        } catch (Exception e) {
            return WeChatNotifyRespDTO.fail(Code.SYSTEM_ERROR.getMsg());
        }
    }

    @PostMapping(value = "/payment", consumes = {MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE}, produces = MediaType.APPLICATION_XML_VALUE)
    public WeChatNotifyRespDTO contractPayment(@RequestBody WeChatPaymentNotifyDTO paymentNotifyDTO) {
        log.info("收到微信支付通知：{}", paymentNotifyDTO);
        weChatNotifyService.create(paymentNotifyDTO.getMerchantId(), paymentNotifyDTO.getOpenId(), paymentNotifyDTO);
        if (paymentNotifyDTO.getReturnCode().equals(WeChatReturnCode.FAIL)) {
            log.error("微信支付失败：{}", paymentNotifyDTO.getReturnMsg());
            return WeChatNotifyRespDTO.success();
        }
        if (paymentNotifyDTO.getResultCode().equals(WeChatReturnCode.FAIL)) {
            log.error("微信支付失败：{}, {}", paymentNotifyDTO.getErrCode(), paymentNotifyDTO.getErrCodeDes());
            return WeChatNotifyRespDTO.success();
        }
        try {
            SortedMap<String, Object> params = WeChatUtil.req2Map(paymentNotifyDTO, true);
            boolean weChatSign = WeChatUtil.verifySign(params, weChatProperties.getApiKey());
            if (!weChatSign) {
                log.error("微信支付通知验签失败：{}", paymentNotifyDTO);
                return WeChatNotifyRespDTO.fail("签名失败");
            } else {
                paymentNotifyDTO.setTradeState(WeChatTradeState.SUCCESS);
                return deviceOrderService.paymentNotify(paymentNotifyDTO);
            }
        } catch (Exception e) {
            return WeChatNotifyRespDTO.fail(Code.SYSTEM_ERROR.getMsg());
        }
    }


}

